package game

import (
	"errors"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo/options"
	"higame/config"
	mongodb "higame/modules/db"
	"higame/modules/utils"
)

var db = mongodb.GetInstance()
var colName = config.Db.Collection.Game

type Schema struct {
	ID           primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
	AddTime      int64              `json:"add_time" bson:"add_time"`
	Name         string             `json:"name" bson:"name" form:"name" binding:"required"`
	Code         string             `json:"code" bson:"code" form:"code" binding:"required"`
	Status       int64              `json:"status" bson:"status" form:"status" binding:"required"`
	Version      string             `json:"version" bson:"version" form:"version" binding:"required"`
	DownUrl      string             `json:"down_url" bson:"down_url" form:"down_url" binding:"required"`
	DownKey      string             `json:"down_key" bson:"down_key" form:"down_key"`
	IsUp         bool               `json:"is_up" bson:"is_up" form:"is_up" `
	Notice       string             `json:"notice" bson:"notice" form:"notice"`
	UpLog        string             `json:"up_log" bson:"up_log" form:"up_log"`
	Icon         string             `json:"icon" bson:"icon" form:"icon" binding:"required"`
	HomePage     string             `json:"home_page" bson:"home_page" form:"home_page" binding:"required"`
	AppName      string             `json:"app_name" bson:"app_name" form:"app_name" binding:"required"`
	Size         int64              `json:"size" bson:"size" form:"size"`
	OtherDownUrl string             `json:"other_down_url" bson:"other_down_url" form:"other_down_url"`
	OtherDownKey string             `json:"other_down_key" bson:"other_down_key" form:"other_down_key"`
	MainImage    string             `json:"main_image" bson:"main_image" form:"main_image"`
	RateScore    float64            `json:"rate_score" bson:"rate_score" form:"rate_score"`
	Category     string             `json:"category" bson:"category" form:"category"`
	ListingDate  int64              `json:"listing_date" bson:"listing_date"`
	DetailText   string             `json:"detail_text" bson:"detail_text"`
	DetailImage  []string           `json:"detail_image" bson:"detail_image"`
}

func New() *Schema {
	return &Schema{}
}

func Parse(bson bson.M) *Schema {
	resolve := utils.NewResolve(bson)
	return &Schema{
		ID:           resolve.ObjectID("_id"),
		AddTime:      resolve.Int64("add_time", 0),
		Name:         resolve.String("name", ""),
		Code:         resolve.String("code", ""),
		Status:       resolve.Int64("status", 0),
		Version:      resolve.String("version", ""),
		DownUrl:      resolve.String("down_url", ""),
		IsUp:         resolve.Bool("is_up", false),
		Notice:       resolve.String("notice", ""),
		UpLog:        resolve.String("up_log", ""),
		Icon:         resolve.String("icon", ""),
		HomePage:     resolve.String("home_page", ""),
		AppName:      resolve.String("app_name", ""),
		OtherDownUrl: resolve.String("other_down_url", ""),
		OtherDownKey: resolve.String("other_down_key", ""),
		MainImage:    resolve.String("main_image", ""),
		RateScore:    resolve.Float64("rate_score", 0),
		Category:     resolve.String("category", ""),
		ListingDate:  resolve.Int64("listing_date", 0),
		Size:         resolve.Int64("size", 0),
		DetailText:   resolve.String("detail_text", ""),
		DownKey:      resolve.String("down_key", ""),
	}
}

func AddOne(schema *Schema) error {
	i := db.InsertOne(colName, schema)
	if !i {
		return fmt.Errorf("添加失败！\n")
	}
	return nil
}

func DeleteByID(id primitive.ObjectID) error {
	r := db.DeleteOne(colName, bson.M{"_id": id})
	if !r {
		return fmt.Errorf("删除失败！\n")
	}
	return nil
}

func UpdateByCode(code string, update interface{}) error {
	r := db.UpdateOne(colName, bson.M{"code": code}, bson.M{
		"$set": update,
	})
	if !r {
		return fmt.Errorf("你没有修改任何数据！\n")
	}
	return nil
}

func FindByID(id primitive.ObjectID) (*Schema, error) {
	userF := db.FindOne(colName, bson.M{"_id": id})
	if userF == nil {
		return nil, errors.New("游戏不存在！")
	}

	user := Parse(userF)
	return user, nil
}

func FindByCode(code string) (*Schema, error) {
	userF := db.FindOne(colName, bson.M{"code": code})
	if userF == nil {
		return nil, errors.New("游戏不存在！")
	}

	user := Parse(userF)
	return user, nil
}

func FindAll(pageNum int64, pageSize int64, filter interface{}) ([]bson.M, error) {
	opts := new(options.FindOptions)
	list := db.FindMany(colName, filter,
		opts.SetSkip(pageNum*pageSize),
		opts.SetLimit(pageSize),
		opts.SetSort(bson.M{
			"rate_score": -1,
		}))
	return list, nil
}

func Count(filter interface{}) (int64, error) {
	return db.Count(colName, filter), nil
}
